package com.mzj.saas.mservice.property.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.mzj.saas.commons.DateUtils;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.SQLUtils;
import com.mzj.saas.commons.enums.BacklogItemTypeEnum;
import com.mzj.saas.commons.util.StringUtils;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.backlog.entity.BacklogItem;
import com.mzj.saas.mservice.backlog.repository.BacklogItemRepository;
import com.mzj.saas.mservice.community.entity.Community;
import com.mzj.saas.mservice.community.entity.CommunityBuild;
import com.mzj.saas.mservice.community.entity.CommunityBuildUnit;
import com.mzj.saas.mservice.community.repository.CommunityBuildRepository;
import com.mzj.saas.mservice.community.repository.CommunityBuildUnitRepository;
import com.mzj.saas.mservice.community.repository.CommunityRepository;
import com.mzj.saas.mservice.department.entity.Department;
import com.mzj.saas.mservice.department.repository.DepartmentRepository;
import com.mzj.saas.mservice.eligible.entity.DepartmentEnterpriseTagRef;
import com.mzj.saas.mservice.eligible.entity.DepartmentHierarchy;
import com.mzj.saas.mservice.eligible.repository.DepartmentEnterpriseTagRefRepository;
import com.mzj.saas.mservice.eligible.repository.DepartmentHierarchyRepository;
import com.mzj.saas.mservice.house.entity.House;
import com.mzj.saas.mservice.house.repository.HouseRepository;
import com.mzj.saas.mservice.property.common.HouseTypeEnum;
import com.mzj.saas.mservice.property.common.RepairsStatusEnum;
import com.mzj.saas.mservice.property.common.ServiceTypeEnum;
import com.mzj.saas.mservice.property.entity.*;
import com.mzj.saas.mservice.property.repository.*;
import com.mzj.saas.mservice.property.vo.*;
import com.mzj.saas.mservice.sys.entity.AppUser;
import com.mzj.saas.mservice.sys.entity.User;
import com.mzj.saas.mservice.sys.repository.AppUserRepository;
import com.mzj.saas.mservice.sys.repository.UserRepository;
import com.mzj.saas.redis.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SingleColumnRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class EstateRepairsRecordService {
    private static final Logger log = LoggerFactory.getLogger(EstateRepairsRecordService.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private NamedParameterJdbcTemplate namedparameterjdbctemplate;
    @Autowired
    private EstateRepairsRecordRepository estateRepairsRecordRepository;
    @Autowired
    private EstateRepairsContentImgService estateRepairsContentImgService;
    @Autowired
    private EstateRepairsCostService estateRepairsCostService;
    @Autowired
    private EstateRepairsCostDetailService estateRepairsCostDetailService;
    @Autowired
    private EstateRepairsEvaluationService estateRepairsEvaluationService;
    @Autowired
    private CommunityRepository communityRepository;
    @Autowired
    private CommunityBuildRepository communityBuildRepository;
    @Autowired
    private CommunityBuildUnitRepository communityBuildUnitRepository;
    @Autowired
    private CommunityHouseUserRepository communityHouseUserRepository;
    @Autowired
    private AppUserRepository appUserRepository;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DepartmentRepository departmentRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private ServiceUserRepository serviceUserRepository;
    @Autowired
    private EstateRepairsContentImgRepository estateRepairsContentImgRepository;
    @Autowired
    private EstateRepairsEvaluationRepository estateRepairsEvaluationRepository;
    @Autowired
    private DepartmentHierarchyRepository departmentHierarchyRepository;
    @Autowired
    private DepartmentEnterpriseTagRefRepository departmentEnterpriseTagRefRepository;
    // @Autowired
    // private MHouseSurrenderRepository mHouseSurrenderRepository;
    @Autowired
    private HouseRepository houseRepository;
    @Autowired
    private BacklogItemRepository backlogItemRepository;
    /**
     * 封装报修数据
     * @param record
     * @param token
     * @return
     */
    private EstateRepairsRecordVO convertToVO(EstateRepairsRecord record, TokenRedisVo token) {
        EstateRepairsRecordVO vo = new EstateRepairsRecordVO();
        BeanUtils.copyProperties(record, vo);

        communityRepository.findById(record.getCommunityId())
                .ifPresent(community -> vo.setCommunityName(community.getName()));
        communityBuildRepository.findById(record.getBuildingNum())
                .ifPresent(communityBuild -> vo.setBuildingNumName(communityBuild.getName()));
        communityBuildUnitRepository.findById(record.getUnit())
                .ifPresent(communityBuildUnit -> vo.setUnitName(communityBuildUnit.getName()));

        vo.setHouseTypeName(HouseTypeEnum.getTypeName(record.getHouseType()));
        vo.setServiceTypeName(ServiceTypeEnum.getTypeName(record.getServiceType()));
        vo.setStatusName(RepairsStatusEnum.getStatusName(record.getStatus()));
        try {
            vo.setContent(new String(record.getContent(), "utf-8"));
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }

        AppUser appUser = appUserRepository.findByIdOrEnterpriseUserId(vo.getOperatorId(), vo.getOperatorId());
        if (appUser != null) {
            vo.setOperatorName(appUser.getName());
        }

        List<EstateRepairsContentImg> imgs = estateRepairsContentImgService.findByRepairsId(record.getId());
        vo.setEstateRepairsContentImgList(imgs);

        return vo;
    }

    @Transactional(rollbackFor = Exception.class)
    public ResultBean<EstateRepairsRecordVO> save(String accessToken, EstateRepairsRecordVO recordVO) {
        TokenRedisVo token = redisService.findTokenVo(accessToken);
        if (token == null)
            return ResultBean.failedResultOfToken();

        //限制退租后用户不能提出报事报修 xiaolong 20230410
        String houseId = recordVO.getHouseId();
        String phone = token.getPhone();
        List<CommunityHouseUser> byCommunityHouseIdAndStatusAndMobile = communityHouseUserRepository.findByCommunityHouseIdAndStatusAndMobile(houseId, 1, phone);
        if (byCommunityHouseIdAndStatusAndMobile.isEmpty()) {
            return ResultBean.failedResultOfParamWithMsg("已退租无法提交报事报修");
        }
        Date date = new Date();

        //新增报修记录
        EstateRepairsRecord record = new EstateRepairsRecord();
        BeanUtils.copyProperties(recordVO, record);
        record.setStatus(RepairsStatusEnum.PENDING.getStatus());
        record.setRepairsTime(date);
        record.setOperatorId(token.getId());
        record.setCreateTime(date);
        record.setLastUpdateTime(date);
        record.setReviewStatus(0);
        record.setOrderId(recordVO.getOrderId());
        record.setAppUserId(token.getId());
        try {
            record.setContent(recordVO.getContent().getBytes("utf-8"));
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        estateRepairsRecordRepository.save(record);

        List<EstateRepairsContentImg> imgs = recordVO.getEstateRepairsContentImgList();
        if (!imgs.isEmpty()) {
            for (EstateRepairsContentImg img : imgs) {
                img.setRepairsId(record.getId());
                estateRepairsContentImgService.save(img);
            }
        }

        EstateRepairsRecordVO estateRepairsRecordVO = convertToVO(record, token);
        return ResultBean.successfulResult(estateRepairsRecordVO);
    }

    /**
     * 查询用户可报修房产
     * @param accessToken
     * @return
     */
    public ResultBean<List<RepairsHouse>> findRepairHouse(String accessToken) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = token.getId();
            Long enterpriseId = token.getEnterpriseId();

            List<String> houseIdList = getHouseIdList(userId, enterpriseId);

            String houseQuery = "SELECT h.id AS house_id,case h.house_nature when 1 then 1 else 2 end AS house_type,case h.house_nature when 1 then '公租房' else '物业房产' end as houseTypeName, \n" +
                    "h.residence_community_id AS community_id,c.name AS community_name, h.building_num AS building_num, b.name AS building_num_name, h.unit, \n" +
                    "u.name AS unit_name, h.room_number,h.floor,h.owner_name as ownerName,h.owner_mobile as ownerMobile,h.org_id,h.house_property_id as housePropertyId FROM saas_house h \n" +
                    "LEFT JOIN saas_community c ON c.id = h.residence_community_id \n" +
                    "LEFT JOIN saas_community_build b ON b.id = h.building_num \n" +
                    "LEFT JOIN saas_community_build_unit u ON u.id = h.unit WHERE h.id in ";

            List<RepairsHouse> list = new ArrayList<>();
            if (!houseIdList.isEmpty()) {
                list = jdbcTemplate.query(houseQuery + SQLUtils.foreachIn(houseIdList.size()), new BeanPropertyRowMapper<>(RepairsHouse.class), houseIdList.toArray());
            }

            if (!list.isEmpty()) {
                // 公租房查询产权单位名称
                List<Long> orgIds = list.stream().filter(RepairsHouse -> RepairsHouse.getOrgId() != null).map(RepairsHouse::getOrgId).distinct().collect(Collectors.toList());
                if (!orgIds.isEmpty()) {
                    Map<Long, String> map = departmentRepository.findByIdIn(orgIds).stream().collect(Collectors.toMap(Department::getId, Department::getName));
                    if (!map.isEmpty()) {
                        list.forEach(repairsHouse -> {
                            if (repairsHouse.getHouseType() == 1) {
                                repairsHouse.setOwnerName(map.get(repairsHouse.getOrgId()));
                            }
                        });
                    }
                }
            }

            return ResultBean.successfulResult(list);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 公租房承租人、公租房同住人、房产租客成员、产权单位、物业，房屋信息查询
     */
    public List<String> getHouseIdList(String userId, Long enterpriseId) {
        String houseSql = "SELECT u.house_id AS houseId \n" +
                "FROM saas_house_match_user u \n" +
                "LEFT JOIN `saas_house` h ON u.house_id = h.`id`\n" +
                "WHERE u.match_user_id = ? AND u.status = 1 AND h.`lease_status` = 1\n" +
                "UNION \n" +
                "SELECT u.house_id AS houseId \n" +
                "FROM saas_house_match_user u\n" +
                "LEFT JOIN `saas_house` h ON u.house_id = h.`id` \n" +
                "LEFT JOIN (SELECT c.apply_id, us.id, us.enterprise_user_id FROM saas_house_eligible_apply_cohabit c LEFT JOIN saas_app_user us ON c.mobile = us.phone) c1 \n" +
                "ON u.apply_id = c1.apply_id \n" +
                "WHERE (c1.id = ? OR c1.enterprise_user_id = ?) AND u.status = 1 AND h.`lease_status` = 1\n" +
                "UNION \n" +
                "SELECT u2.community_house_id AS houseId \n" +
                "FROM saas_community_house_user u2\n" +
                "LEFT JOIN `saas_house` h ON u2.community_house_id = h.`id` \n" +
                "LEFT JOIN saas_app_user us ON us.phone = u2.mobile\n" +
                "WHERE (us.id = ? OR us.enterprise_user_id = ?) AND u2.status = 1 \n" +
                "UNION \n" +
                "SELECT h.id AS houseId \n" +
                "FROM `saas_house` h \n" +
                "WHERE h.`org_id` = ? or h.`house_property_id` = ?";
        return jdbcTemplate.query(houseSql, new SingleColumnRowMapper<>(String.class), userId, userId, userId, userId, userId, enterpriseId, enterpriseId);
    }

    /**
     * 报修记录列表
     *
     * @param accessToken
     * @param houseId 房产id
     * @param communityId 小区
     * @param buildId 楼宇
     * @param unitId 单元
     * @param roomNumber 房号
     * @param floor 楼层
     * @param operatorName 发起人姓名
     * @param operatorMobile 发起人电话
     * @param startTime 发起时间
     * @param endTime 结束时间
     * @param type 报修状态
     * @param status 0无 1已申请 2已验房 3未结清 4已结清 6已完成
     * @param pageNumber
     * @param pageSize
     * 可查询管辖区域报修记录 维修人员app登录只能查看自己负责的维修信息
     */
    public ResultBean<EstateRepairsRecordApiData<EstateRepairsRecordVO>> list(String accessToken, String houseId,
                                                                              String communityId, Long buildId, Long unitId, String roomNumber, Integer floor, String operatorName,
                                                                              String operatorMobile, String startTime, String endTime, Integer type, Integer status, Integer pageNumber,
                                                                              Integer pageSize) {
        try {
            //校验登录信息
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null) {
                return ResultBean.failedResultOfToken();
            }
            //登录场景1.PC端登录 2.APP登录
            Integer flag = token.getFlag();
            //id
            String userId = token.getId();
            String phone = token.getPhone();
            //企业标识
            Long enterpriseId = token.getEnterpriseId();


            Map<String, Object> params = new HashMap<>();

            String mobile = null;
            String serviceUserId = null;
            if (flag == 1) {//PC端登录
                User user = userRepository.findUserById(userId);
                mobile = user.getMobile();
            }
            if (flag == 2) {//APP登录
                AppUser appUser = appUserRepository.findByIdOrEnterpriseUserId(userId, userId);
                mobile = appUser.getPhone();
            }
            //根据用户ID，获取退租信息，并获取退租状态
            // MHouseSurrender mHouseSurrender = mHouseSurrenderRepository.findByOperatorId(userId);
            // Integer surrenderStatus = mHouseSurrender.getStatus();
            // if (surrenderStatus ==1)  {
            //     return ResultBean.successfulResult(null);
            // }
            //维修人员信息
            ServiceUser serviceUser = serviceUserRepository.findByMobile(mobile);
            String sql = "";
            //String newSql = "";
            if (serviceUser != null) {
                //维修人员只能查看自己的维修单
                sql = " where (serr.operator_id = :userId or serr.service_user_id = :serviceUserId)";
                serviceUserId = serviceUser.getId().toString();
                params.put("serviceUserId", serviceUserId);
            } else {
                // sql = " WHERE (serr.operator_id = :userId or h.house_property_id = :housePropertyId)";
                // params.put("housePropertyId", enterpriseId);
                //    修复bug用户换了房屋之后不能看到自己在之前房屋提交的报事报修信息
                // sql = " WHERE (serr.operator_id = :userId and chu.mobile = :phone and chu.status = 1)";
                sql = " WHERE (chu.mobile = :phone and chu.status = 1 AND chu.operator_time <= serr.create_time AND serr.house_id = :houseId )";
                params.put("phone",phone);
                params.put("houseId",houseId);
            }
            if (enterpriseId != null) {
                //根据企业ID查询出用户层级权限
                DepartmentHierarchy hierarchy = departmentHierarchyRepository.findByOrgIdAndStatus(enterpriseId, 1);
                if (hierarchy == null) {
                    return ResultBean.failedResultWithMsg("用户所属机构未设置层级架构");
                }
                //获取企业用户ID
                Long id = hierarchy.getId();
                //根据企业用户ID获取公租房数据
                List<DepartmentEnterpriseTagRef> refs = departmentEnterpriseTagRefRepository.findByDepRefId(id);
                //获取企业标签集合
                List<Long> enterpriseTagIds = refs.stream().map(DepartmentEnterpriseTagRef::getTagId).distinct().collect(Collectors.toList());//用户企业标签
                if (enterpriseTagIds.contains(4L)) {
                    sql = " WHERE (serr.operator_id = :userId or h.house_property_id = :housePropertyId or h.org_id = :orgId)";
                    //newSql = " WHERE (serr.operator_id = :userId or a.dep_id= :housePropertyId)";
                    params.put("housePropertyId", enterpriseId);
                    params.put("orgId", enterpriseId);
                } else {
                    return ResultBean.successfulResult(null);
                }
            }
            params.put("userId", userId);
            params.put("limit", pageSize);
            params.put("offset", pageNumber * pageSize);

            EstateRepairsRecordApiData<EstateRepairsRecordVO> apiData = new EstateRepairsRecordApiData<>();
            // 判断用户是否已经被移除房屋，如果是，则不返回数据
            // CommunityHouseUser communityHouseUser = communityHouseUserRepository.findByUserIdAndMobileAndStatus(userId, mobile, 1);
            // if (communityHouseUser == null) {
            //     return ResultBean.failedResult(apiData);
            // }
            String querySql;
            String countSql;
            String pendingTotalSql;
            String awaitingRepairTotalSql;
            String repairingTotalSql;
            String awaitingPayTotalSql;
            String completedTotalSql;
            if (serviceUser != null) {
                querySql = "SELECT serr.*,h.house_property_id,u.name as serviceUserName,serr.content AS contentTemp FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "left join saas_app_user au1 on serr.operator_id = au1.id \n" +
                        "LEFT JOIN saas_app_user au2 ON serr.operator_id = au2.enterprise_user_id" + sql;

                countSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "left join saas_app_user au1 on serr.operator_id = au1.id \n" +
                        "LEFT JOIN saas_app_user au2 ON serr.operator_id = au2.enterprise_user_id" + sql;

                pendingTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 0";

                awaitingRepairTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 1";

                repairingTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 2";

                awaitingPayTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 3";

                completedTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 4";
            } else {
                //修复bug用户换了房屋之后不能看到自己在之前房屋提交的报事报修信息
                querySql = "SELECT serr.*,h.house_property_id,u.name as serviceUserName,serr.content AS contentTemp FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "left join saas_app_user au1 on serr.operator_id = au1.id \n" +
                        "LEFT JOIN saas_app_user au2 ON serr.operator_id = au2.enterprise_user_id \n" +
                        "LEFT JOIN saas_community_house_user chu ON serr.house_id = chu.community_house_id "+ sql;

                countSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "left join saas_app_user au1 on serr.operator_id = au1.id \n" +
                        "LEFT JOIN saas_app_user au2 ON serr.operator_id = au2.enterprise_user_id \n" +
                        "LEFT JOIN saas_community_house_user chu ON serr.house_id = chu.community_house_id " + sql;

                pendingTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "LEFT JOIN saas_community_house_user chu ON serr.house_id = chu.community_house_id " + sql + " AND serr.status = 0";

                awaitingRepairTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "LEFT JOIN saas_community_house_user chu ON serr.house_id = chu.community_house_id " + sql + " AND serr.status = 1";

                repairingTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "LEFT JOIN saas_community_house_user chu ON serr.house_id = chu.community_house_id " + sql + " AND serr.status = 2";

                awaitingPayTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "LEFT JOIN saas_community_house_user chu ON serr.house_id = chu.community_house_id " + sql + " AND serr.status = 3";

                completedTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "LEFT JOIN saas_community_house_user chu ON serr.house_id = chu.community_house_id " + sql + " AND serr.status = 4";
            }
            if (enterpriseId != null) {
                querySql = "SELECT serr.*,h.house_property_id,u.name as serviceUserName,serr.content AS contentTemp FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "left join saas_app_user au1 on serr.operator_id = au1.id \n" +
                        "LEFT JOIN saas_app_user au2 ON serr.operator_id = au2.enterprise_user_id \n" + sql;
                        //"left join saas_user_department_ref a on a.user_id = au1.enterprise_user_id " + sql;

                countSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id \n" +
                        "left join saas_app_user au1 on serr.operator_id = au1.id \n" +
                        "LEFT JOIN saas_app_user au2 ON serr.operator_id = au2.enterprise_user_id \n" + sql;
                        //"left join saas_user_department_ref a on a.user_id = au1.enterprise_user_id " + sql;


                pendingTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 0";

                awaitingRepairTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 1";

                repairingTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 2";

                awaitingPayTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 3";

                completedTotalSql = "SELECT COUNT(*) FROM saas_estate_repairs_record serr left join saas_house h on serr.house_id = h.id \n" +
                        "left join saas_service_user u on serr.service_user_id = u.id" + sql + " AND serr.status = 4";
            }
            if (!StringUtils.isEmpty(houseId)) {
                params.put("houseId", houseId);
                querySql += " AND serr.house_id = :houseId ";
                countSql += " AND serr.house_id = :houseId ";
                pendingTotalSql += " AND serr.house_id = :houseId ";
                awaitingRepairTotalSql += " AND serr.house_id = :houseId ";
                repairingTotalSql += " AND serr.house_id = :houseId ";
                awaitingPayTotalSql += " AND serr.house_id = :houseId ";
                completedTotalSql += " AND serr.house_id = :houseId ";
            }

            if (!StringUtils.isEmpty(communityId)) {
                params.put("communityId", communityId);
                querySql += " AND serr.community_id = :communityId ";
                countSql += " AND serr.community_id = :communityId ";
                pendingTotalSql += " AND serr.community_id = :communityId ";
                awaitingRepairTotalSql += " AND serr.community_id = :communityId ";
                repairingTotalSql += " AND serr.community_id = :communityId ";
                awaitingPayTotalSql += " AND serr.community_id = :communityId ";
                completedTotalSql += " AND serr.community_id = :communityId ";
            }

            if (buildId != null) {
                params.put("buildId", buildId);
                querySql += " AND serr.building_num = :buildId ";
                countSql += " AND serr.building_num = :buildId ";
                pendingTotalSql += " AND serr.building_num = :buildId ";
                awaitingRepairTotalSql += " AND serr.building_num = :buildId ";
                repairingTotalSql += " AND serr.building_num = :buildId ";
                awaitingPayTotalSql += " AND serr.building_num = :buildId ";
                completedTotalSql += " AND serr.building_num = :buildId ";
            }

            if (unitId != null) {
                params.put("unitId", unitId);
                querySql += " AND serr.unit = :unitId ";
                countSql += " AND serr.unit = :unitId ";
                pendingTotalSql += " AND serr.unit = :unitId ";
                awaitingRepairTotalSql += " AND serr.unit = :unitId ";
                repairingTotalSql += " AND serr.unit = :unitId ";
                awaitingPayTotalSql += " AND serr.unit = :unitId ";
                completedTotalSql += " AND serr.unit = :unitId ";
            }

            if (!StringUtils.isEmpty(roomNumber)) {
                params.put("roomNumber", roomNumber);
                querySql += " AND serr.room_number = :roomNumber ";
                countSql += " AND serr.room_number = :roomNumber ";
                pendingTotalSql += " AND serr.room_number = :roomNumber ";
                awaitingRepairTotalSql += " AND serr.room_number = :roomNumber ";
                repairingTotalSql += " AND serr.room_number = :roomNumber ";
                awaitingPayTotalSql += " AND serr.room_number = :roomNumber ";
                completedTotalSql += " AND serr.room_number = :roomNumber ";
            }

            if (floor != null) {
                params.put("floor", floor);
                querySql += " AND serr.floor = :floor ";
                countSql += " AND serr.floor = :floor ";
                pendingTotalSql += " AND serr.floor = :floor ";
                awaitingRepairTotalSql += " AND serr.floor = :floor ";
                repairingTotalSql += " AND serr.floor = :floor ";
                awaitingPayTotalSql += " AND serr.floor = :floor ";
                completedTotalSql += " AND serr.floor = :floor ";
            }

            if (!StringUtils.isEmpty(operatorName)) {
                params.put("operatorName", operatorName);
                querySql += " AND (au1.name = :operatorName or au2.name = :operatorName) ";
                countSql += " AND (au1.name = :operatorName or au2.name = :operatorName) ";
                /*pendingTotalSql += " AND (au1.name = :operatorName or au2.name = :operatorName) ";
                awaitingRepairTotalSql += " AND (au1.name = :operatorName or au2.name = :operatorName) ";
                repairingTotalSql += " AND (au1.name = :operatorName or au2.name = :operatorName) ";
                awaitingPayTotalSql += " AND (au1.name = :operatorName or au2.name = :operatorName) ";
                completedTotalSql += " AND (au1.name = :operatorName or au2.name = :operatorName) ";*/
            }

            if (!StringUtils.isEmpty(operatorMobile)) {
                params.put("operatorMobile", operatorMobile);
                querySql += " AND (au1.phone = :operatorMobile or au2.phone = :operatorMobile) ";
                countSql += " AND (au1.phone = :operatorMobile or au2.phone = :operatorMobile) ";
                /*pendingTotalSql += " AND (au1.phone = :operatorMobile or au2.phone = :operatorMobile) ";
                awaitingRepairTotalSql += " AND (au1.phone = :operatorMobile or au2.phone = :operatorMobile) ";
                repairingTotalSql += " AND (au1.phone = :operatorMobile or au2.phone = :operatorMobile) ";
                awaitingPayTotalSql += " AND (au1.phone = :operatorMobile or au2.phone = :operatorMobile) ";
                completedTotalSql += " AND (au1.phone = :operatorMobile or au2.phone = :operatorMobile) ";*/
            }

            if (!StringUtils.isEmpty(startTime) && !StringUtils.isEmpty(endTime)) {
                params.put("startTime", startTime);
                params.put("endTime", DateUtils.getAddDaysTime(endTime, DateUtils.FORMAT_DATE_8, 1));
                querySql += " AND serr.repairs_time >= :startTime AND serr.repairs_time < :endTime";
                countSql += " AND serr.repairs_time >= :startTime AND serr.repairs_time < :endTime";
                pendingTotalSql += " AND serr.repairs_time >= :startTime AND serr.repairs_time < :endTime";
                awaitingRepairTotalSql += " AND serr.repairs_time >= :startTime AND serr.repairs_time < :endTime";
                repairingTotalSql += " AND serr.repairs_time >= :startTime AND serr.repairs_time < :endTime";
                awaitingPayTotalSql += " AND serr.repairs_time >= :startTime AND serr.repairs_time < :endTime";
                completedTotalSql += " AND serr.repairs_time >= :startTime AND serr.repairs_time < :endTime";
            }

            if (type != null) {
                params.put("type", type);
                querySql += " AND serr.service_type = :type";
                countSql += " AND serr.service_type = :type";
                pendingTotalSql += " AND serr.service_type = :type";
                awaitingRepairTotalSql += " AND serr.service_type = :type";
                repairingTotalSql += " AND serr.service_type = :type";
                awaitingPayTotalSql += " AND serr.service_type = :type";
                completedTotalSql += " AND serr.service_type = :type";
            }

            if (status != null) {
                params.put("status", status);
                querySql += " AND serr.status = :status ";
                countSql += " AND serr.status = :status ";
                //pendingTotalSql += " AND serr.status = :status ";
                //awaitingRepairTotalSql += " AND serr.status = :status ";
                //repairingTotalSql += " AND serr.status = :status ";
                //awaitingPayTotalSql += " AND serr.status = :status ";
                //completedTotalSql += " AND serr.status = :status ";
            }

            querySql += " order by serr.create_time desc";
            querySql += " LIMIT :limit OFFSET :offset";
            //总数
            Long count = namedparameterjdbctemplate.queryForObject(countSql, params, Long.class);
            log.info(countSql + params);
            //待处理
            Long pendingTotal = namedparameterjdbctemplate.queryForObject(pendingTotalSql, params, Long.class);
            //待维修
            Long awaitingRepairTotal = namedparameterjdbctemplate.queryForObject(awaitingRepairTotalSql, params, Long.class);
            //维修中
            Long repairingTotal = namedparameterjdbctemplate.queryForObject(repairingTotalSql, params, Long.class);
            //待缴费
            Long awaitingPayTotal = namedparameterjdbctemplate.queryForObject(awaitingPayTotalSql, params, Long.class);
            //已完成
            Long completedTotal = namedparameterjdbctemplate.queryForObject(completedTotalSql, params, Long.class);
            //数据
            List<EstateRepairsRecordVO> recordList = namedparameterjdbctemplate.query(querySql, params,
                    new BeanPropertyRowMapper<>(EstateRepairsRecordVO.class));
            log.info(querySql + params);
            for (EstateRepairsRecordVO vo : recordList) {
                //操作人标识：0是 1否
                if (userId.equals(vo.getOperatorId())) {
                    vo.setOperatorFlag(1);
                } else {
                    vo.setOperatorFlag(0);
                }
                //维修人员标识：0是 1否
                if (StringUtils.isNotBlank(serviceUserId) && StringUtils.isNotBlank(vo.getServiceUserId()) && serviceUserId.equals(vo.getServiceUserId())) {
                    vo.setServiceFlag(1);
                } else {
                    vo.setServiceFlag(0);
                }
                //物业标识：0是 1否
                if (enterpriseId != null && vo.getHousePropertyId() != null && enterpriseId.longValue() == vo.getHousePropertyId()) {
                    vo.setPropertyFlag(1);
                } else {
                    vo.setPropertyFlag(0);
                }

                vo.setHouseTypeName(HouseTypeEnum.getTypeName(vo.getHouseType()));
                vo.setServiceTypeName(ServiceTypeEnum.getTypeName(vo.getServiceType()));
                vo.setStatusName(RepairsStatusEnum.getStatusName(vo.getStatus()));
                vo.setContent(new String(vo.getContentTemp(),"utf-8"));

                List<EstateRepairsContentImg> imgs = estateRepairsContentImgService.findByRepairsId(vo.getId());
                vo.setEstateRepairsContentImgList(imgs);
            }

            // 查询小区名称
            List<String> communityIds = recordList.stream().filter(vo -> vo.getCommunityId() != null).map(EstateRepairsRecordVO::getCommunityId).distinct().collect(Collectors.toList());
            if (!communityIds.isEmpty()) {
                Map<String, String> map = communityRepository.findByIdIn(communityIds).stream().collect(Collectors.toMap(Community::getId, Community::getName));
                if (!map.isEmpty()) {
                    recordList.forEach(vo -> vo.setCommunityName(map.get(vo.getCommunityId())));
                }
            }
            // 查询楼栋名称
            List<Long> buildingIds = recordList.stream().filter(vo -> vo.getBuildingNum() != null).map(EstateRepairsRecordVO::getBuildingNum).distinct().collect(Collectors.toList());
            if (!buildingIds.isEmpty()) {
                Map<Long, String> map = communityBuildRepository.findByIdIn(buildingIds).stream().filter(vo -> vo.getName() != null).collect(Collectors.toMap(CommunityBuild::getId, CommunityBuild::getName));
                if (!map.isEmpty()) {
                    recordList.forEach(vo -> vo.setBuildingNumName(map.get(vo.getBuildingNum())));
                }
            }
            // 查询单元名称
            List<Long> unitIds = recordList.stream().filter(vo -> vo.getUnit() != null).map(EstateRepairsRecordVO::getUnit).distinct().collect(Collectors.toList());
            if (!unitIds.isEmpty()) {
                Map<Long, String> map = communityBuildUnitRepository.findByIdIn(unitIds).stream().collect(Collectors.toMap(CommunityBuildUnit::getId, CommunityBuildUnit::getName));
                if (!map.isEmpty()) {
                    recordList.forEach(vo -> vo.setUnitName(map.get(vo.getUnit())));
                }
            }
            //查询操作人名称
            List<String> operatorIds = recordList.stream().filter(vo -> vo.getOperatorId() != null).map(EstateRepairsRecordVO::getOperatorId).distinct().collect(Collectors.toList());
            if (!operatorIds.isEmpty()) {
                List<AppUser> appUsers = appUserRepository.findByUserIdOrEnterpriseIn(operatorIds, operatorIds);
                for (AppUser appUser : appUsers) {
                    for (EstateRepairsRecordVO vo : recordList) {
                        if (vo.getOperatorId().equals(appUser.getId()) || vo.getOperatorId().equals(appUser.getEnterpriseUserId())) {
                            vo.setOperatorName(appUser.getName());
                            vo.setOperatorMobile(appUser.getPhone());
                        }
                    }
                }
            }

            apiData.setTotal(count);
            apiData.setPendingTotal(pendingTotal);
            apiData.setAwaitingRepairTotal(awaitingRepairTotal);
            apiData.setRepairingTotal(repairingTotal);
            apiData.setAwaitingPayTotal(awaitingPayTotal);
            apiData.setCompletedTotal(completedTotal);
            apiData.setData(recordList);

            return ResultBean.successfulResult(apiData);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * @param accessToken          token
     * @param residenceCommunityId 小区id
     * @param buildingNum          楼栋
     * @param unit                 单元
     * @param roomNumber           房号
     * @return RepairsHouse
     */
    public ResultBean<List<RepairsHouse>> findNonPersonalProperty(String accessToken, String residenceCommunityId,
                                                                  Long buildingNum, Long unit, String roomNumber) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            String houseQuery = "SELECT h.id AS house_id,case h.house_nature when 1 then 1 else 2 end AS house_type,\n" +
                    "case h.house_nature when 1 then '公租房' else '物业房产' end as houseTypeName,h.residence_community_id AS community_id,c.name AS community_name,\n" +
                    "h.building_num AS building_num, b.name AS building_num_name, h.unit AS unit, u.name AS unit_name, h.room_number,\n" +
                    "h.floor,h.owner_name as ownerName,h.owner_mobile as ownerMobile,h.org_id,h.house_property_id,h.address \n" +
                    "FROM saas_house h LEFT JOIN saas_community c ON c.id = h.residence_community_id \n" +
                    "LEFT JOIN saas_community_build b ON b.id = h.building_num \n" +
                    "LEFT JOIN saas_community_build_unit u ON u.id = h.unit ";

            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where 1 = 1");

            if (StringUtils.isNotBlank(residenceCommunityId)) {
                where.append(" and h.residence_community_id = ?");
                args.add(residenceCommunityId);
            }
            if (buildingNum != null) {
                where.append(" and h.building_num = ?");
                args.add(buildingNum);
            }
            if (unit != null) {
                where.append(" and h.unit = ?");
                args.add(unit);
            }
            if (StringUtils.isNotBlank(roomNumber)) {
                where.append(" and h.room_number = ?");
                args.add(roomNumber);
            }

            List<RepairsHouse> list = jdbcTemplate.query(houseQuery + where, new BeanPropertyRowMapper<>(RepairsHouse.class), args.toArray());

            if (!list.isEmpty()) {
                // 公租房查询产权单位名称
                List<Long> orgIds = list.stream().filter(RepairsHouse -> RepairsHouse.getOrgId() != null).map(RepairsHouse::getOrgId).distinct().collect(Collectors.toList());
                if (!orgIds.isEmpty()) {
                    Map<Long, String> map = departmentRepository.findByIdIn(orgIds).stream().collect(Collectors.toMap(Department::getId, Department::getName));
                    if (!map.isEmpty()) {
                        list.forEach(repairsHouse -> {
                            if (repairsHouse.getHouseType() == 1) {
                                repairsHouse.setOwnerName(map.get(repairsHouse.getOrgId()));
                            }
                        });
                    }
                }
            }

            return ResultBean.successfulResult(list);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 报修分配
     * @param accessToken
     * @param id
     * @param serviceUserId
     * @return
     */
    @Transactional
    public ResultBean<EstateRepairsRecordVO> assign(String accessToken, Long id, String serviceUserId) {
        TokenRedisVo token = redisService.findTokenVo(accessToken);
        if (token == null)
            return ResultBean.failedResultOfToken();

        String sql = "UPDATE saas_estate_repairs_record SET service_user_id = ?, status = ?, last_update_time = ? WHERE id = ?";
        int update = jdbcTemplate.update(sql, serviceUserId, RepairsStatusEnum.AWAITING_REPAIR.status, new Date(), id);

        if (update == 1) { //分派成功
            EstateRepairsRecord repairsRecord = estateRepairsRecordRepository.findById(id).orElse(null);
            //报修记录
            EstateRepairsRecordVO estateRepairsRecordVO = convertToVO(repairsRecord, token);


            // 新增消息推送
            BacklogItem backlogItem = new BacklogItem();
            backlogItem.setHouseId(repairsRecord.getHouseId());
            // 如果是公租房取产权单位id，如果是非公租房取物业公司id
            backlogItem.setType(BacklogItemTypeEnum.COMPLAIN_SUGGEST_ASSIGN.getValue());
            backlogItem.setTitle("报事报修已分派");
            List<House> houseList = houseRepository.findByIdAndStatus(repairsRecord.getHouseId(), 1);
            if (CollectionUtil.isEmpty(houseList)) {
                return ResultBean.failedResultWithMsg("房屋不存在");
            }
            House house = houseList.get(0);
            Optional<Community> community = communityRepository.findById(house.getResidenceCommunityId());
            Optional<CommunityBuild> communityBuild = communityBuildRepository.findById(house.getBuildingNum());
            Optional<CommunityBuildUnit> communityBuildUnit = communityBuildUnitRepository.findById(house.getUnit());
            backlogItem.setContent(community.get().getName() + communityBuild.get().getName() + "栋" + communityBuildUnit.get().getName() + "单元" + house.getRoomNumber() + "号，报事报修已分派给维修人员，请等待！" );
            backlogItem.setBusinessStatus("待查看");
            backlogItem.setHandleStatus(0);// 0未读/未处理
            backlogItem.setOperatorId(repairsRecord.getOperatorId());
            backlogItem.setCreateTime(new Date());
            backlogItem.setMatchUserId(repairsRecord.getAppUserId());

            backlogItemRepository.save(backlogItem);


            return ResultBean.successfulResult(estateRepairsRecordVO);
        } else {
            return ResultBean.failedResultWithMsg("分派失败");
        }
    }

    /**
     * 修改状态为维修中
     * @param accessToken
     * @param id
     * @return
     */
    @Transactional
    public ResultBean<Object> fix(String accessToken, Long id) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            String sql = "UPDATE saas_estate_repairs_record SET status = ?, last_update_time = ? WHERE id = ?";
            jdbcTemplate.update(sql, RepairsStatusEnum.REPAIRING.status, new Date(), id);


            // 新增消息推送
            EstateRepairsRecord repairsRecord = estateRepairsRecordRepository.findById(id).orElse(null);
            BacklogItem backlogItem = new BacklogItem();
            backlogItem.setHouseId(repairsRecord.getHouseId());
            // 如果是公租房取产权单位id，如果是非公租房取物业公司id
            backlogItem.setType(BacklogItemTypeEnum.COMPLAIN_SUGGEST_FIX.getValue());
            backlogItem.setTitle("报事报修维修中");
            List<House> houseList = houseRepository.findByIdAndStatus(repairsRecord.getHouseId(), 1);
            House house = houseList.get(0);
            Optional<Community> community = communityRepository.findById(house.getResidenceCommunityId());
            Optional<CommunityBuild> communityBuild = communityBuildRepository.findById(house.getBuildingNum());
            Optional<CommunityBuildUnit> communityBuildUnit = communityBuildUnitRepository.findById(house.getUnit());
            backlogItem.setContent(community.get().getName() + communityBuild.get().getName() + "栋" + communityBuildUnit.get().getName() + "单元" + house.getRoomNumber() + "号，报事报修维修中！" );
            backlogItem.setBusinessStatus("待查看");
            backlogItem.setHandleStatus(0);// 0未读/未处理
            backlogItem.setOperatorId(repairsRecord.getOperatorId());
            backlogItem.setCreateTime(new Date());
            backlogItem.setMatchUserId(repairsRecord.getAppUserId());

            backlogItemRepository.save(backlogItem);


            return ResultBean.successfulResult(null);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ResultBean<List<EstateRepairsCostDetailVO>> addCosts(String accessToken, Long id,
                                                                List<EstateRepairsCostVO> estateRepairsCostVOList) {
        try {
            log.info("estateRepairsRecordService addCosts id={},estateRepairsCostVOList={}",id, JSONObject.toJSON(estateRepairsCostVOList));
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            for (EstateRepairsCostVO costVO : estateRepairsCostVOList) {
                EstateRepairsCost cost = estateRepairsCostService.findById(costVO.getId());

                EstateRepairsCostDetail costDetail = new EstateRepairsCostDetail();
                costDetail.setRepairsId(id);
                costDetail.setCostId(cost.getId());
                costDetail.setMaterialsCost(cost.getMaterialsCost());
                costDetail.setServiceCost(cost.getServiceCost());
                costDetail.setTotalCost(cost.getMaterialsCost() + cost.getServiceCost());

                estateRepairsCostDetailService.save(costDetail);
            }

            String sql = "UPDATE saas_estate_repairs_record SET status = ?, last_update_time = ? WHERE id = ?";
            jdbcTemplate.update(sql, RepairsStatusEnum.AWAITING_PAY.status, new Date(), id);


            // 新增消息推送
            EstateRepairsRecord repairsRecord = estateRepairsRecordRepository.findById(id).orElse(null);
            BacklogItem backlogItem = new BacklogItem();
            backlogItem.setHouseId(repairsRecord.getHouseId());
            // 如果是公租房取产权单位id，如果是非公租房取物业公司id
            backlogItem.setType(BacklogItemTypeEnum.COMPLAIN_SUGGEST_FEE.getValue());
            backlogItem.setTitle("报事报修收费项目");
            List<House> houseList = houseRepository.findByIdAndStatus(repairsRecord.getHouseId(), 1);
            House house = houseList.get(0);
            Optional<Community> community = communityRepository.findById(house.getResidenceCommunityId());
            Optional<CommunityBuild> communityBuild = communityBuildRepository.findById(house.getBuildingNum());
            Optional<CommunityBuildUnit> communityBuildUnit = communityBuildUnitRepository.findById(house.getUnit());
            backlogItem.setContent(community.get().getName() + communityBuild.get().getName() + "栋" + communityBuildUnit.get().getName() + "单元" + house.getRoomNumber() + "号，报事报修待缴费！" );
            backlogItem.setBusinessStatus("待查看");
            backlogItem.setHandleStatus(0);// 0未读/未处理
            backlogItem.setOperatorId(repairsRecord.getOperatorId());
            backlogItem.setCreateTime(new Date());
            backlogItem.setMatchUserId(repairsRecord.getAppUserId());// 承租人

            backlogItemRepository.save(backlogItem);

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 报修收费项目明细
     * @param accessToken
     * @param id
     * @return
     */
    public ResultBean<List<EstateRepairsCostDetailVO>> getCosts(String accessToken, Long id) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            //报修收费项目明细
            List<EstateRepairsCostDetail> costDetails = estateRepairsCostDetailService.findByRepairsId(id);

            List<EstateRepairsCostDetailVO> costDetailVOList = new ArrayList<>();
            for (EstateRepairsCostDetail costDetail : costDetails) {
                EstateRepairsCostDetailVO costDetailVO = estateRepairsCostDetailService.convertToVO(costDetail);
                costDetailVOList.add(costDetailVO);
            }

            return ResultBean.successfulResult(costDetailVOList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<EstateRepairsEvaluationVO> getEvaluation(String accessToken, Long id) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            EstateRepairsEvaluation evaluation = estateRepairsEvaluationService.findByRepairsId(id);
            if (evaluation == null) {
                return ResultBean.successfulResult(null);
            }

            EstateRepairsEvaluationVO vo = new EstateRepairsEvaluationVO();
            vo.setId(evaluation.getId());
            vo.setRepairsId(evaluation.getRepairsId());
            vo.setLevel(evaluation.getLevel());
            vo.setContent(new String(evaluation.getContent()));

            return ResultBean.successfulResult(vo);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    //@Transactional()
    public ResultBean<EstateRepairsEvaluation> addEvaluation(String accessToken,
                                                             EstateRepairsEvaluationVO vo) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            Long repairsId = vo.getRepairsId();
            if (estateRepairsEvaluationService.isExist(repairsId)) {
                return ResultBean.failedResultWithMsg("该报修记录已评价，不可重复评价");
            }

            EstateRepairsEvaluation evaluation = new EstateRepairsEvaluation();
            evaluation.setRepairsId(repairsId);
            evaluation.setLevel(vo.getLevel());
            evaluation.setContent(vo.getContent().getBytes());
            EstateRepairsEvaluation save = estateRepairsEvaluationRepository.save(evaluation);

            //更新评论状态
            String sql = "UPDATE saas_estate_repairs_record SET review_status = ?, last_update_time = ? WHERE id = ?";
            jdbcTemplate.update(sql, 1, new Date(), vo.getRepairsId());

            return ResultBean.successfulResult(save);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 维修完成
     * @param accessToken
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultBean<Object> fixComplete(String accessToken, Long id) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            String sql = "UPDATE saas_estate_repairs_record SET status = ?, last_update_time = ? WHERE id = ?";
            jdbcTemplate.update(sql, RepairsStatusEnum.COMPLETED.status, new Date(), id);


            // 新增消息推送
            EstateRepairsRecord repairsRecord = estateRepairsRecordRepository.findById(id).orElse(null);
            BacklogItem backlogItem = new BacklogItem();
            backlogItem.setHouseId(repairsRecord.getHouseId());
            // 如果是公租房取产权单位id，如果是非公租房取物业公司id
            backlogItem.setType(BacklogItemTypeEnum.COMPLAIN_SUGGEST_FIX.getValue());
            backlogItem.setTitle("报事报修已完成");
            List<House> houseList = houseRepository.findByIdAndStatus(repairsRecord.getHouseId(), 1);
            House house = houseList.get(0);
            Optional<Community> community = communityRepository.findById(house.getResidenceCommunityId());
            Optional<CommunityBuild> communityBuild = communityBuildRepository.findById(house.getBuildingNum());
            Optional<CommunityBuildUnit> communityBuildUnit = communityBuildUnitRepository.findById(house.getUnit());
            backlogItem.setContent(community.get().getName() + communityBuild.get().getName() + "栋" + communityBuildUnit.get().getName() + "单元" + house.getRoomNumber() + "号，报事报修已维修完成！" );
            backlogItem.setBusinessStatus("待查看");
            backlogItem.setHandleStatus(0);// 0未读/未处理
            backlogItem.setOperatorId(repairsRecord.getOperatorId());
            backlogItem.setCreateTime(new Date());
            backlogItem.setMatchUserId(repairsRecord.getAppUserId());
            backlogItemRepository.save(backlogItem);


            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional
    public ResultBean<Object> delete(String accessToken, Long id) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            estateRepairsRecordRepository.deleteById(id);
            estateRepairsContentImgRepository.deleteByRepairsId(id);

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<Object> find(String accessToken, Long id) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();

            Optional<EstateRepairsRecord> recordOptional = estateRepairsRecordRepository.findById(id);
            EstateRepairsRecord record = recordOptional.get();

            EstateRepairsRecordVO vo = new EstateRepairsRecordVO();
            BeanUtils.copyProperties(record, vo);

            try {
                vo.setContent(new String(record.getContent(), "utf-8"));
            }catch (Exception e){
                log.error(e.getMessage(),e);
            }

            return ResultBean.successfulResult(vo);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }


}
